package com.example.composetest

import androidx.compose.runtime.Composable
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import app.cash.molecule.AndroidUiDispatcher
import app.cash.molecule.RecompositionMode
import app.cash.molecule.launchMolecule
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.SharedFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.launch

abstract class MVIViewModel<State, Event, Effect> : ViewModel() {
    private val scope = CoroutineScope(viewModelScope.coroutineContext + AndroidUiDispatcher.Main)
    private val events = MutableSharedFlow<Event>()
    val state: StateFlow<State> by lazy(LazyThreadSafetyMode.NONE) {
        scope.launchMolecule(mode = RecompositionMode.ContextClock) {
            state(events)
        }
    }

    @Composable
    protected abstract fun state(events: Flow<Event>): State

    fun sendEvent(event: Event) {
        viewModelScope.launch {
            events.emit(event)
        }
    }

    private val _effects = MutableSharedFlow<Effect>()
    val effects: SharedFlow<Effect> = _effects

    protected fun processEffects(effect: Effect) {
        viewModelScope.launch {
            _effects.emit(effect)
        }
    }
}